﻿// Decompiled with JetBrains decompiler
// Type: Commom.Util.RsaHelper
// Assembly: MT5Trade, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 8045A2CB-DBD6-41AD-8804-F98CAC1BDC8D
// Assembly location: C:\projects\trade\trade_tool\trade0812\MT5Trade.dll

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

#nullable enable
namespace Commom.Util;

internal class RsaHelper
{
  private readonly RSA _privateKeyRsaProvider;
  private readonly RSA _publicKeyRsaProvider;
  private readonly HashAlgorithmName _hashAlgorithmName;
  private readonly Encoding _encoding;

  public RsaHelper(RSAType rsaType, Encoding encoding, string privateKey = null, string publicKey = null)
  {
    this._encoding = encoding;
    if (!string.IsNullOrEmpty(privateKey))
      this._privateKeyRsaProvider = this.CreateRsaProviderFromPrivateKey(privateKey);
    if (!string.IsNullOrEmpty(publicKey))
      this._publicKeyRsaProvider = this.CreateRsaProviderFromPublicKey(publicKey);
    this._hashAlgorithmName = rsaType == RSAType.RSA ? HashAlgorithmName.SHA1 : HashAlgorithmName.SHA256;
  }

  public string Sign(string data)
  {
    return Convert.ToBase64String(this._privateKeyRsaProvider.SignData(this._encoding.GetBytes(data), this._hashAlgorithmName, RSASignaturePadding.Pkcs1));
  }

  public bool Verify(string data, string sign)
  {
    return this._publicKeyRsaProvider.VerifyData(this._encoding.GetBytes(data), Convert.FromBase64String(sign), this._hashAlgorithmName, RSASignaturePadding.Pkcs1);
  }

  public string Decrypt(string cipherText)
  {
    if (this._privateKeyRsaProvider == null)
      throw new Exception("_privateKeyRsaProvider is null");
    return Encoding.UTF8.GetString(this._privateKeyRsaProvider.Decrypt(Convert.FromBase64String(cipherText), RSAEncryptionPadding.Pkcs1));
  }

  public string Encrypt(string text)
  {
    if (this._publicKeyRsaProvider == null)
      throw new Exception("_publicKeyRsaProvider is null");
    return Convert.ToBase64String(this._publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.Pkcs1));
  }

  public RSA CreateRsaProviderFromPrivateKey(string privateKey)
  {
    byte[] buffer = Convert.FromBase64String(privateKey);
    RSA providerFromPrivateKey = RSA.Create();
    RSAParameters parameters = new RSAParameters();
    using (BinaryReader binr = new BinaryReader((Stream) new MemoryStream(buffer)))
    {
      switch (binr.ReadUInt16())
      {
        case 33072:
          int num1 = (int) binr.ReadByte();
          break;
        case 33328:
          int num2 = (int) binr.ReadInt16();
          break;
        default:
          throw new Exception("Unexpected value read binr.ReadUInt16()");
      }
      if (binr.ReadUInt16() != (ushort) 258)
        throw new Exception("Unexpected version");
      parameters.Modulus = binr.ReadByte() == (byte) 0 ? binr.ReadBytes(this.GetIntegerSize(binr)) : throw new Exception("Unexpected value read binr.ReadByte()");
      parameters.Exponent = binr.ReadBytes(this.GetIntegerSize(binr));
      parameters.D = binr.ReadBytes(this.GetIntegerSize(binr));
      parameters.P = binr.ReadBytes(this.GetIntegerSize(binr));
      parameters.Q = binr.ReadBytes(this.GetIntegerSize(binr));
      parameters.DP = binr.ReadBytes(this.GetIntegerSize(binr));
      parameters.DQ = binr.ReadBytes(this.GetIntegerSize(binr));
      parameters.InverseQ = binr.ReadBytes(this.GetIntegerSize(binr));
    }
    providerFromPrivateKey.ImportParameters(parameters);
    return providerFromPrivateKey;
  }

  public RSA CreateRsaProviderFromPublicKey(string publicKeyString)
  {
    byte[] b = new byte[15]
    {
      (byte) 48 /*0x30*/,
      (byte) 13,
      (byte) 6,
      (byte) 9,
      (byte) 42,
      (byte) 134,
      (byte) 72,
      (byte) 134,
      (byte) 247,
      (byte) 13,
      (byte) 1,
      (byte) 1,
      (byte) 1,
      (byte) 5,
      (byte) 0
    };
    byte[] numArray1 = new byte[15];
    using (MemoryStream input = new MemoryStream(Convert.FromBase64String(publicKeyString)))
    {
      using (BinaryReader binaryReader = new BinaryReader((Stream) input))
      {
        switch (binaryReader.ReadUInt16())
        {
          case 33072:
            int num1 = (int) binaryReader.ReadByte();
            break;
          case 33328:
            int num2 = (int) binaryReader.ReadInt16();
            break;
          default:
            return (RSA) null;
        }
        if (!this.CompareBytearrays(binaryReader.ReadBytes(15), b))
          return (RSA) null;
        switch (binaryReader.ReadUInt16())
        {
          case 33027:
            int num3 = (int) binaryReader.ReadByte();
            break;
          case 33283:
            int num4 = (int) binaryReader.ReadInt16();
            break;
          default:
            return (RSA) null;
        }
        if (binaryReader.ReadByte() != (byte) 0)
          return (RSA) null;
        switch (binaryReader.ReadUInt16())
        {
          case 33072:
            int num5 = (int) binaryReader.ReadByte();
            break;
          case 33328:
            int num6 = (int) binaryReader.ReadInt16();
            break;
          default:
            return (RSA) null;
        }
        ushort num7 = binaryReader.ReadUInt16();
        byte num8 = 0;
        byte num9;
        switch (num7)
        {
          case 33026:
            num9 = binaryReader.ReadByte();
            break;
          case 33282:
            num8 = binaryReader.ReadByte();
            num9 = binaryReader.ReadByte();
            break;
          default:
            return (RSA) null;
        }
        int int32 = BitConverter.ToInt32(new byte[4]
        {
          num9,
          num8,
          (byte) 0,
          (byte) 0
        }, 0);
        if (binaryReader.PeekChar() == 0)
        {
          int num10 = (int) binaryReader.ReadByte();
          --int32;
        }
        byte[] numArray2 = binaryReader.ReadBytes(int32);
        if (binaryReader.ReadByte() != (byte) 2)
          return (RSA) null;
        int count = (int) binaryReader.ReadByte();
        byte[] numArray3 = binaryReader.ReadBytes(count);
        RSA providerFromPublicKey = RSA.Create();
        providerFromPublicKey.ImportParameters(new RSAParameters()
        {
          Modulus = numArray2,
          Exponent = numArray3
        });
        return providerFromPublicKey;
      }
    }
  }

  private int GetIntegerSize(BinaryReader binr)
  {
    if (binr.ReadByte() != (byte) 2)
      return 0;
    byte num1 = binr.ReadByte();
    int integerSize;
    switch (num1)
    {
      case 129:
        integerSize = (int) binr.ReadByte();
        break;
      case 130:
        byte num2 = binr.ReadByte();
        integerSize = BitConverter.ToInt32(new byte[4]
        {
          binr.ReadByte(),
          num2,
          (byte) 0,
          (byte) 0
        }, 0);
        break;
      default:
        integerSize = (int) num1;
        break;
    }
    while (binr.ReadByte() == (byte) 0)
      --integerSize;
    binr.BaseStream.Seek(-1L, SeekOrigin.Current);
    return integerSize;
  }

  private bool CompareBytearrays(byte[] a, byte[] b)
  {
    if (a.Length != b.Length)
      return false;
    int index = 0;
    foreach (int num in a)
    {
      if (num != (int) b[index])
        return false;
      ++index;
    }
    return true;
  }
}
